<?php

namespace app\common\model\merchant;

use app\common\loader\ModelShop;
use app\common\model\BaseModel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;

/**
 * 商户库存
 * Class MerchantStock
 * @package app\common\model\merchant
 */
class MerchantStockModel extends BaseModel
{
    //
    protected $name = 'merchant_stock';

    // 设置字段信息
    protected $schema = [
        'mer_id' => 'string',        // 所属商户
        'balance' => 'float',        // 余额
        'virtual_num' => 'int',        // 虚码数量
        'real_num' => 'int',        // 实码数量
        'update_at' => 'datetime',        // 更新时间
    ];


    /**
     * 用户余额编辑
     * @param string     $merId 商户编号
     * @param int        $type 类型  1增加 2减少
     * @param float      $chang_money 变更金额
     * @param string     $remark 备注
     * @param int        $opUser 管理id
     * @param string     $pay_order 关联支付单号
     * @param int|string $reason_type 原因类型
     * @return int|string
     * @throws Exception
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function userBalanceEdit(string $merId, int $type, float $chang_money, string $remark, int $opUser, string $pay_order = '', $reason_type = 0)
    {
        $userInfo = $this->where('mer_id', $merId)->field('mer_id,balance')->find();
        if (empty($userInfo)) {
            throw new  Exception('用户未找到', API_ERROR);
        }
        if ($chang_money === floatval(0)) {
            throw new  Exception('调整金额不能为0', API_ERROR);
        }
        //用户金额增加
        if ($type === MONEY_CHANGE_ADD)
            $reMoney = $userInfo['balance'] + $chang_money;
        else {
            $reMoney = $userInfo['balance'] - $chang_money;
            if ($reMoney < 0) {
                throw new  Exception('余额不足,请及时充值', API_ERROR);
            }
        }
        $this->db()->where('mer_id', $merId)->update(['balance' => $reMoney]);
        $reasonList = config('system.money_log_reason', []);
        return $this->db('merchant_money_log')->insert([
            'mer_id' => $merId,
            'type' => $type,
            'money' => $chang_money,  //变动金额
            're_money' => $reMoney,  //变动后金额
            'memo' => $remark,
            'pay_order' => $pay_order,
            'op_user' => $opUser,
            'create_at' => date('Y-m-d H:i:s'),
            'reason' => $reasonList[$reason_type] ?? '其他',
        ]);
    }

    /**
     * 用户虚码变化
     * @param string $merId 商户编号
     * @param int    $type 变动类型
     * @param int    $num 变动数量
     * @param string $remark 备注
     * @param int    $opUser 操作人
     * @param int    $shopId 相关店铺
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function userVirtualEdit(string $merId, int $type, int $num, string $remark, int $opUser, int $shopId = 0)
    {
        $userInfo = $this->where('mer_id', $merId)->field('mer_id,virtual_num')->find();
        if (empty($userInfo)) {
            throw new  Exception('用户未找到', API_ERROR);
        }
        if ($num === 0) {
            throw new  Exception('虚码数不能为0', API_ERROR);
        }
        //用户金额增加
        if ($type === MONEY_CHANGE_ADD) {
            $reNum = $userInfo['virtual_num'] + $num;
        } else {

            if ($userInfo['virtual_num'] < $num) {
                throw new  Exception('虚码数不足', API_ERROR);
            }
            $reNum = $userInfo['virtual_num'] - $num;
        }
        $this->db()->where('mer_id', $merId)->update(['virtual_num' => $reNum]);
        if ($shopId > 0) {
            $title = ModelShop::Shop()->getShopTitle($shopId, 'title');
            if (!empty($title)) {
                $remark .= '. (' . $title . ')';
            }
        }
        return $this->db('virtual_transaction')->insert([
            'mer_id' => $merId,
            'flag' => 1,
            'type' => $type,
            'num' => $num,  //变动数
            're_num' => $reNum,  //变动后
            'memo' => $remark,
            'shop_id' => $shopId,
            'op_user' => $opUser,
            'create_at' => date('Y-m-d H:i:s'),
        ]);
    }

    /**
     * 获取商户的库存数
     * @param string $merId
     * @param string $field
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function getStockInfo(string $merId, string $field = '')
    {
        $info = $this->db()->alias('a')->join('merchant_info b', 'a.mer_id=b.mer_id')
            ->where('a.mer_id', $merId)
            ->field('a.mer_id,balance,virtual_num,real_num,b.company_name,b.end_time')->find();
        if (empty($info)) {
            throw  new Exception('商户不存在', API_ERROR);
        }
        return $info;
    }

    /**
     * 获取商户统计信息
     * @param string $mer_id 商户编号
     */
    public function getUserStatistics(string $mer_id)
    {
        return  $this->db()->where('mer_id', $mer_id)
            ->field('mer_id as stock_info , mer_id as product_num, mer_id as shop_num,mer_id as salesman_num,
           mer_id as virtual_promo_num,mer_id as order_num,balance,virtual_num,real_num')
            ->withAttr([
                'product_num' => function ($value) {
                    return $this->db('product')->where('mer_id', $value)->whereNull('delete_at')->count('id');
                },
                'shop_num' => function ($value) {
                    return $this->db('shop')->where('mer_id', $value)
                        ->cache(true, MINUTES_SECOND_5)->count('id');
                },
                'salesman_num' => function ($value) {
                    return $this->db('shop_salesman')->where('mer_id', $value)
                        ->field('count(id) as all_num, SUM(case when status<1 then 1 else 0 end)')
                        ->cache(true, MINUTES_SECOND_5)
                        ->find();
                },
                'virtual_promo_num' => function ($value) {
                    return $this->db('shop_salesman')->where('mer_id', $value)
                        ->cache(true, MINUTES_SECOND_5)
                        ->count('id');
                },
                'order_num' => function ($value) {
                    return $this->db('virtual_used_log')->where(['mer_id' => $value, 'status' => 0])
                            ->cache(true, MINUTES_SECOND_5)
                            ->count('id');
                }
            ])->find();

    }
}
